package com.example.foobar.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.foobar.business.service.DaQrcodeRetentionRatesService;
import com.example.foobar.business.service.ImsGhostCustomActiveRecordService;
import com.example.foobar.dao.service.DaQrcodeRetentionRatesDaoService;
import com.example.foobar.dto.DABaseDTO;
import com.example.foobar.dto.RetentionRateDTO;
import com.example.foobar.entity.DaQrcodeRetentionRates;
import com.example.foobar.entity.DaRemark;
import com.example.foobar.utils.Utils;
import com.example.foobar.vo.RetentionRateVO;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import io.geekidea.springbootplus.framework.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 本地公众号信息 服务实现类
 *
 * @author 郑英奔
 * @since 2021-05-31
 */
@Slf4j
@Service
public class DaQrcodeRetentionRatesServiceImpl implements DaQrcodeRetentionRatesService {

    @Autowired
    DaQrcodeRetentionRatesDaoService daQrcodeRetentionRatesDaoService;

    @Autowired
    ImsGhostCustomActiveRecordService imsGhostCustomActiveRecordService;

    @Override
    public boolean saveDaQrcodeRetentionRates(DaQrcodeRetentionRates daQrcodeRetentionRates) {
        return daQrcodeRetentionRatesDaoService.saveDaQrcodeRetentionRates(daQrcodeRetentionRates);
    }

    @Override
    public boolean updateDaQrcodeRetentionRates(DaQrcodeRetentionRates daQrcodeRetentionRates) {
        return daQrcodeRetentionRatesDaoService.updateDaQrcodeRetentionRates(daQrcodeRetentionRates);
    }

    @Override
    public boolean deleteDaQrcodeRetentionRates(Long id) {
        return daQrcodeRetentionRatesDaoService.deleteDaQrcodeRetentionRates(id);
    }

    @Override
    public DaQrcodeRetentionRates getById(Long id) {
        return daQrcodeRetentionRatesDaoService.getById(id);
    }

    @Override
    public void remove(LambdaQueryWrapper<DaQrcodeRetentionRates> wrapper) {
        daQrcodeRetentionRatesDaoService.remove(wrapper);
    }

    @Override
    public void saveBatch(List<DaQrcodeRetentionRates> daRetentionRatesList) {
        daQrcodeRetentionRatesDaoService.saveBatch(daRetentionRatesList);
    }

    @Override
    public Paging<RetentionRateVO> getQrCodeStroyRetentonRates(String sceneId, Date startDate, Date endDate, int dayCount) {
        List<RetentionRateVO> retentionRateVOS = new ArrayList<>();
        ZonedDateTime zonedDateTime = LocalDate.now().atStartOfDay(ZoneId.systemDefault());
        Date today =Date.from(zonedDateTime.toInstant());
        while(!startDate.after(endDate)){
            RetentionRateVO retentionRateVO = new RetentionRateVO();

            List<RetentionRateDTO> stroyRetentonRates = daQrcodeRetentionRatesDaoService.getQrCodeStroyRetentonRates(sceneId, startDate, DateUtils.addDays(startDate, dayCount));
            Map<String, RetentionRateDTO> collect = stroyRetentonRates.stream().collect(Collectors.toMap(a -> {
                Date retentionRateDate = a.getRetentionRateDate();
                String dateString = DateUtil.getDateString(retentionRateDate);
                return dateString;
            }, Function.identity(), (key1, key2) -> key2));

            Date rateDate = startDate;
            while(rateDate.before(DateUtils.addDays(startDate, dayCount))){
                String dateString = DateUtil.getDateString(rateDate);
                if(dateString.equals(DateUtil.getDateString(today))){
                    rateDate = DateUtils.addDays(rateDate, 1);
                    continue;
                }
                if(!collect.containsKey(dateString)){
                    stroyRetentonRates.add(new RetentionRateDTO(null, sceneId,startDate,rateDate));
                }
                rateDate = DateUtils.addDays(rateDate, 1);
            }

//            LambdaQueryWrapper<DaRemark> wrapper = new LambdaQueryWrapper<>(DaRemark.class).eq(DaRemark::getUniacid, sceneId)
//                    .eq(DaRemark::getBaseDate, startDate);
//            DaRemark daRemark = daRemarkDaoService.selectOne(wrapper);

//            Collections.sort(stroyRetentonRates, (o1, o2) -> o1.getRetentionRateDate().compareTo(o2.getRetentionRateDate()));
            retentionRateVO.setDate(DateFormatUtils.format(startDate, "yyyy-MM-dd"));
            retentionRateVO.setNewCommerCount(stroyRetentonRates.get(0).getNewComerCount());
            retentionRateVO.setRateDTOS(stroyRetentonRates);
//            retentionRateVO.setRemark(daRemark != null ? daRemark.getRemark() : "");
            retentionRateVOS.add(retentionRateVO);
            startDate = DateUtils.addDays(startDate, 1);
//            index ++;
        }

        addTodayDataRate(sceneId, retentionRateVOS);

        Collections.sort(retentionRateVOS,  (o1, o2) -> o2.getDate().compareTo(o1.getDate()));
        IPage<RetentionRateVO> page = new Page<>();
        page.setPages(1);
        page.setRecords(retentionRateVOS);
        page.setCurrent(1);
        page.setSize(1);
        page.setTotal(7);
        Paging<RetentionRateVO> paging = new Paging<RetentionRateVO>(page);
        return paging;
    }

    private void addTodayDataRate(String sceneId, List<RetentionRateVO> retentionRateVOS) {
        ZonedDateTime zonedDateTime = LocalDate.now().atStartOfDay(ZoneId.systemDefault());
        Date today =Date.from(zonedDateTime.toInstant());
        List<String> messageTypeList = new ArrayList<>();
        messageTypeList.add(DaNewCommerCountServiceImpl.MESSAGE_TYPE_EVENT);
        messageTypeList.add(DaNewCommerCountServiceImpl.MESSAGE_TYPE_TEXT);
        retentionRateVOS.forEach(retentionRateVO -> {
            try {
                Date baseDate = DateUtils.parseDate(retentionRateVO.getDate(), "yyyy-MM-dd");
                List<DABaseDTO> activeDataByOfficialAccountIdAndDataRange = imsGhostCustomActiveRecordService.getActiveDataByOfficialSenceIdAndDataRange(sceneId, baseDate, today, today, messageTypeList);
                RetentionRateDTO todayRate = new RetentionRateDTO();

                int subscribeCount = imsGhostCustomActiveRecordService.getSubscribeCountBySceneId(sceneId, baseDate);

                if(baseDate.compareTo(today) == 0){
                    retentionRateVO.setNewCommerCount(subscribeCount);
                }
                todayRate.setBaseDate(baseDate);
                todayRate.setSceneId(sceneId);
                todayRate.setRetentionRateDate(today);
                todayRate.setNewComerCount(subscribeCount);
                todayRate.setRetentionAmount(activeDataByOfficialAccountIdAndDataRange.size() == 0 ? 0 : activeDataByOfficialAccountIdAndDataRange.get(0).getCount());
                todayRate.setRetentionRate(activeDataByOfficialAccountIdAndDataRange.size() == 0 ? "/" : Utils.formateRate(activeDataByOfficialAccountIdAndDataRange.get(0).getCount(), subscribeCount));
                retentionRateVO.getRateDTOS().add(todayRate);
                Collections.sort(retentionRateVO.getRateDTOS(), (o1, o2) -> o1.getRetentionRateDate().compareTo(o2.getRetentionRateDate()));
            } catch (ParseException e) {
                e.printStackTrace();
            }

        });
    }
}
